﻿import * as chartjsExt from "../../js/chartjs-ext.js";


export function createChart(chartCanvasId, csThis) {
    let domCanvas = document.getElementById(chartCanvasId);
    if (domCanvas == null)
        return;

    let chartConfig = {
        type: 'line',
        data: {
            labels: []
        },
        options: {
            animation: false,
            maintainAspectRatio: false,
            interaction: {
                // Overrides the global setting
                mode: 'index',
                intersect: false
            },
            scales: {
                x: {
                    type: "linear",
                },
                y: {
                    beginAtZero: false
                }
            },

            onResize: function (chart, dim) {
                //console.log(chart);
                if (chart.ext != undefined)
                    csThis.invokeMethodAsync('UpdateByShotsOnce');
            },
            onHover: function (evt, item, chart) {
                //console.log(evt);
                //console.log(item);
                //console.log(chart.scales.x.getValueForPixel(evt.x));

                let xDim = chart.scales.x.max - chart.scales.x.min;
                chart.ext.xPositionPercentage
                    = (chart.scales.x.getValueForPixel(evt.x) - chart.scales.x.min) / xDim;

                if (item.length)
                    csThis.invokeMethodAsync('EnterStripPos', item[0].index);
            },
            onClick: function (evt, item, chart) {
                //console.log(evt);
                let clickedTimeText = chartjsExt.toStopWatchTimeDetailString(item[0].element.$context.parsed.x);
                //console.log("clicked-time", clickedTimeText);
                document.getElementById('timechart-free-textarea').innerHTML += "\n"+clickedTimeText;
                //console.log(chart);
                if (item.length)
                    csThis.invokeMethodAsync('SelectStripPos', item[0].index);
            },
            plugins: {
                legend: {
                    display: false,
                },
                tooltip: {
                    callbacks: {
                        title: function (context) {
                            if (!context[0].chart.ext.is_xaxis_time_category) {
                                let dst = '';
                                if (context[0].dataIndex > 0 && context[0].chart.ext.is_xaxis_range_mode)
                                    dst += context[0].chart.data.labels[context[0].dataIndex - 1] + ' ~ ';
                                dst += context[0].label;
                                return dst;
                            }
                            let dst = '';
                            if (context[0].dataIndex > 0 && context[0].chart.ext.is_xaxis_range_mode)
                                dst += chartjsExt.toStopWatchTimeDetailString(context[0].chart.data.labels[context[0].dataIndex - 1]) + ' ~ ';
                            dst = dst + chartjsExt.toStopWatchTimeDetailString(context[0].parsed.x);
                            return dst;
                        }
                    }
                }
            }
        }
    };
    let chart = new Chart(domCanvas, chartConfig);
    domCanvas.chart = chart;
    chart.ext = {
        is_xaxis_time_category: false,
        is_xaxis_range_mode: true,
    };
    chart.options.scales.x.ticks.callback = function (value, index, ticks) {
        if (!chart.ext.is_xaxis_time_category)
            return value;

        let v = value;
        if (!Number.isFinite(v))
            return;
        return chartjsExt.toStopWatchTimeDetailString(v);
    };

    setChartDataSetsMinMax(domCanvas);

    regChartCallback(chart, csThis);
    //console.log(chart);
}
function setChartDataSetsMinMax(domCanvas) {
    if (domCanvas == null)
        return;
    domCanvas.chart.data.datasets = [{
        label: 'Max',
        data: [],
        borderWidth: 1,
        borderColor: '#00F',
        backgroundColor: '#00A4',
        pointRadius: 0,
    }, {
        label: 'Min',
        data: [],
        borderWidth: 1,
        borderColor: '#04F',
        backgroundColor: '#04A4',
        pointRadius: 0,
        fill: 0,
    }];
}

let localRegCallbackResult = null;
function regChartCallback(chart, csThis) {

    //set passive false to avoid chrome scroll bar invocation.
    let funcMouseWheelXyz = function (e) {
        e.preventDefault();

        let xPositionPercentage = chart.ext.xPositionPercentage;
        if (xPositionPercentage === undefined)
            return;

        //console.log('e', e.deltaX, e.deltaY, e.deltaZ, xPositionPercentage);

        //chart.ext.lastMouseMoveEvent
        csThis.invokeMethodAsync('MouseWheel', e.deltaX, e.deltaY, e.deltaZ,
            xPositionPercentage);
    };
    //console.log(chart);
    chart.canvas?.addEventListener('mousewheel', funcMouseWheelXyz, { passive: false });

    localRegCallbackResult = {
        chart: chart,
        funcMouseWheelXyz: funcMouseWheelXyz
    };
}
export function dispose() {
    if (localRegCallbackResult) {
        localRegCallbackResult.chart.canvas?.removeEventListener('mousewheel', localRegCallbackResult.funcMouseWheelXyz);
        localRegCallbackResult.chart.options.onResize = null;
        localRegCallbackResult.chart.options.onHover = null;
        localRegCallbackResult.chart.options.onClick = null;
    }
}

export function setChartData(chartCanvasId, xs, ymins, ymaxs,
    is_xaxis_time_category, is_xaxis_range_mode) {

    //console.log('xs', xs);

    let domCanvas = document.getElementById(chartCanvasId);
    if (domCanvas == null)
        return;
    let chart = domCanvas.chart;
    //console.log("setChartData", domCanvas, domCanvas.chart);
    //console.log('xs',xs);
    //console.log('ymins', ymins);
    //console.log('ymaxs', ymaxs);

    if (xs.length > 0) {
        chart.options.scales.x.min = xs[0];
        //console.log("setChartData.B");
        chart.options.scales.x.max = xs.slice(-1);
    }
    //console.log("setChartData.C");
    if (is_xaxis_range_mode)
        chart.data.datasets.forEach(dataset => dataset.pointRadius = 0);
    else
        chart.data.datasets.forEach(dataset => dataset.pointRadius = 1);
    //console.log("setChartData.D");
    //console.log('a', chart, 'b', chart.data);
    chart.data.labels = xs;
    chart.data.datasets[1].data = ymins;
    chart.data.datasets[0].data = ymaxs;
    chart.ext.is_xaxis_range_mode = is_xaxis_range_mode;
    chart.ext.is_xaxis_time_category = is_xaxis_time_category;
    //    console.log(xs);
    //    console.log(chart.data.labels);
    //console.log("setChartData.E");
}

export function setChartVRange(chartCanvasId, vmin, vmax) {
    let domCanvas = document.getElementById(chartCanvasId);
    if (domCanvas == null)
        return;
    let chart = domCanvas.chart;
    //console.log('a');
    //console.log(vmin);
    //console.log(vmax);
    chart.options.scales.y.min = vmin;
    chart.options.scales.y.max = vmax;
    chart.update();
}

//get chart plotting area width.
export function getChartAreaWidth(chartCanvasId) {
    let domCanvas = document.getElementById(chartCanvasId);
    //console.log(domCanvas?.chart);
    return domCanvas?.chart?.chartArea?.width ?? 0;
}
export function getCanvasDivWidth(chartCanvasId) {
    let domCanvas = document.getElementById(chartCanvasId);
    //console.log(domCanvas.offsetWidth);
    return domCanvas?.offsetWidth ?? 0;
}

export function triggerHover(chartCanvasId, chartPointIndex) {
    let domCanvas = document.getElementById(chartCanvasId);
    if (domCanvas == null)
        return;
    let chart = domCanvas.chart;
    //console.log(chartPointIndex);
    if (chartPointIndex > -1) {
        let dst = chart.data.datasets.map((dataset, i) => ({
            datasetIndex: i,
            index: chartPointIndex,
        }));
        chart.setActiveElements(dst);
        const tooltip = chart.tooltip;
        tooltip.setActiveElements(dst);
    }
    else {
        chart.setActiveElements([]);
        const tooltip = chart.tooltip;
        tooltip.setActiveElements([]);
    }

    chart.update();
}
